package com.xiaotu.spider.maoyan.pageprocessor;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.xiaotu.common.exception.SpiderException;
import com.xiaotu.common.exception.SpiderExceptionCode;
import com.xiaotu.common.model.MaoYanMoviePeopleSupplementModel;
import com.xiaotu.common.util.CacheHandler;
import com.xiaotu.common.util.Constants;
import com.xiaotu.common.util.HtmlUtil;
import com.xiaotu.common.util.PageUtils;
import com.xiaotu.common.util.PropertiesUtil;
import com.xiaotu.common.util.RegexUtils;
import com.xiaotu.common.util.SepratorUtil;
import com.xiaotu.spider.APageProcessor;

import net.sf.json.JSONObject;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Request;
import us.codecraft.webmagic.selector.Html;

@Component("MaoYanMoviePeopleSupplementPageProcessor")
public class MaoYanMoviePeopleSupplementPageProcessor extends APageProcessor {
	
	@Autowired
	private CacheHandler cacheHandler;
	
	private Map<String,String> cookies = new HashMap<String,String>();
	
	{ 
		cookies.put("Cookie", PropertiesUtil.getProperty("BoxOffice.site.Cookie"));
	}
	
	
	public static final String BASEINFO_URL = "http://piaofang.maoyan.com/movie/%s/wantindex?wkwebview=1&city_tier=0&city_id=0&cityName=全国";//人群信息
	
	
	@SuppressWarnings("unchecked")
	@Override
	protected Request getStartRequest(JSONObject target) {
		Request request = new Request(String.format(BASEINFO_URL, target.getString("dataid")));
		request.setExtras((Map<String, Object>)target);
		return request;
	}
	
	@Override
	public void process(Page page) {
		
		Map<String, Object> extrasMap = page.getRequest().getExtras();
		
		switch (this.getPageDataType(page))
        {
           
            case Constants.PageDataType.BASICINFO:
                this.peopleProcess(page,extrasMap);
                break;	
        }
	}

	@Override
	public String getPageDataType(Page page) {
		String url = page.getUrl().toString();
        if (url.contains("http://piaofang.maoyan.com/movie")){
        	return Constants.PageDataType.BASICINFO;
        }
        return null;
	}
	
	@Override
	protected String getSpiderType() {
		return Constants.SpiderTaskType.MOVIE_BOXOFFICE;
	}
	
	
	private void peopleProcess(Page page, Map<String, Object> extraMap) {
		
		String url = page.getRequest().getUrl();
		
		String dataId = extraMap.get("dataid").toString();
		
		String tvName = extraMap.get("tvname").toString();
		
		Html html = null;
		
		if(url.contains(dataId)){
			//解密数据
			try {
				
				html = PageUtils.spiderAudienceRating(page,cookies);
				
			} catch (Exception e) {
				System.exit(0);
			}
	        
			List<String> ageNameList = new ArrayList<>();
			List<String> areaNameList = new ArrayList<>();
			List<String> ageValueList = new ArrayList<>();
			List<String> areaValueList = new ArrayList<>();
			
			String[][] sexData = new String[2][];
			String[][] eduData = new String[2][];
			String[][] occpData = new String[2][];
			String[][] labelData = new String[2][];
	        
			List<String> divList = html.xpath("//div[@class='stackcolumn']").all();
	        
	        if (divList != null && !divList.isEmpty()){
	        	ageNameList = html.xpath("//svg[@id='ageData']/g[@class='x']//text/text()")
		                .all();
		        ageNameList = clearSpaces(ageNameList);
		        ageValueList = html.xpath
		                ("//svg[@id='ageData']/g[@class='bar-group']//text/text()").all();
		        ageValueList = clearSpaces(ageValueList);
		        //this.namesAndValuesValidate(ageNameList, ageValueList);
		        //转换数据
		        Map<String, List<String>> convertNamesAndValuesMap = convertNamesAndValues(ageNameList,ageValueList);
		        ageNameList = convertNamesAndValuesMap.get("nameList");
		        ageValueList = convertNamesAndValuesMap.get("valueList");
		        
		        
		        sexData = this.getLineNamesAndValues(divList, "性别");
		        eduData = this.getLineNamesAndValues(divList, "教育");

		        areaNameList = html.xpath
		                ("//section[@class='area-section']//div[@class='linebars-content']/div[2]/text()").all();
		        areaNameList = clearSpaces(areaNameList);
		        areaValueList = html.xpath
		                ("//section[@class='area-section']//div[@class='linebars-content']//div[@class='linebars-value']/text()").all();
		        areaValueList = clearSpaces(areaValueList);
		        //this.namesAndValuesValidate(areaNameList, areaValueList);
		        //转换数据
		        Map<String, List<String>> convertMap = convertNamesAndValues(areaNameList,areaValueList);
		        areaNameList = convertMap.get("nameList");
		        areaValueList = convertMap.get("valueList");
		        
		        occpData = this.getPieNamesAndValues(html, "occupData");
		        labelData = this.getPieNamesAndValues(html, "interestData");
			
		        
		        page.putField(MaoYanMoviePeopleSupplementModel.class.getName(), new MaoYanMoviePeopleSupplementModel(
		        		dataId,tvName,
		        		sexData[0], sexData[1],
		        		ageNameList.toArray(new String[ageNameList.size()]), ageValueList.toArray(new String[ageValueList.size()]),
		        		eduData[0], eduData[1],
		        		areaNameList.toArray(new String[areaNameList.size()]), areaValueList.toArray(new String[areaValueList.size()]),
		        		occpData[0], occpData[1],
		        		labelData[0], labelData[1]
		        		));
		        
			//cacheHandler.hSet("MAOYAN_SEARCH_MOVIE_NEW", extraMap.get("dataid").toString()+"_"+tvName, extraMap);
			cacheHandler.hDel("ERROR_INFO", extraMap.get("dataid").toString()+"_"+tvName);
	        }
		}
		
	}
	
	
	private String[][] getPieNamesAndValues(Html html, String tagId)
    {
        List<String> occpList = html.xpath("//svg[@id='" + tagId +
                "']/path[@class='pie-item']/@data-info").all();
        if (occpList == null || occpList.isEmpty())
            throw new SpiderException(SpiderExceptionCode.DataInvalideException);
        List<String> occpNameList = occpList.stream().filter(data -> data.split(";").length > 1)
                .map(data -> data.split(";")[1]).collect(Collectors.toList());
        List<String> occpValueList = occpList.stream().filter(data -> data.split(";").length > 1)
                .map(data -> data.split(";")[0]).collect(Collectors.toList());
        //this.namesAndValuesValidate(occpNameList, occpValueList);
        if(tagId.equals("occupData")){
        	//转换数据
            Map<String, List<String>> convertNamesAndValuesMap = convertNamesAndValues(occpNameList,occpValueList);
            occpNameList = convertNamesAndValuesMap.get("nameList");
            occpValueList = convertNamesAndValuesMap.get("valueList");
        }
        return new String[][]{occpNameList.toArray(new String[occpNameList.size()]),
                occpValueList.toArray(new String[occpValueList.size()])};
    }
	
	private String[][] getLineNamesAndValues(List<String> divList, String type)
    {
        String sexDiv = divList.stream().filter(divStr -> divStr.contains(type)).findFirst().get();
        if (StringUtils.isEmpty(sexDiv))
            throw new SpiderException(SpiderExceptionCode.DataInvalideException);
        Html sexHtml = new Html(sexDiv);
        List<String> nameList = sexHtml.xpath("//span[@class='stackcolumn-desc-text']/text()")
                .all();
        List<String> valueList = sexHtml.xpath("//i[@class='cs']/text()").all();
        //this.namesAndValuesValidate(nameList, valueList);
        if(type.contains("性别")||type.contains("教育")){
        	String[] returnNameArr = new String[nameList.size()];
        	String[] returnValueArr = new String[valueList.size()];
        	for(int i = 0;i<nameList.size();i++){
            	
            	if(nameList.get(i).contains("男")){
            		returnNameArr[0] = nameList.get(i);
        			returnValueArr[0] = valueList.get(i);
            	}
            	else if(nameList.get(i).contains("女")){
            		returnNameArr[1] = nameList.get(i);
        			returnValueArr[1] = valueList.get(i);
            	}
            	else if(nameList.get(i).contains("本科及以上")){
            		returnNameArr[0] = nameList.get(i);
        			returnValueArr[0] = valueList.get(i);
            	}
            	else if(nameList.get(i).contains("本科以下")){
            		returnNameArr[1] = nameList.get(i);
        			returnValueArr[1] = valueList.get(i);
            	}
            }
        	nameList = Arrays.asList(returnNameArr);
        	valueList = Arrays.asList(returnValueArr);
        }
        valueList = valueList.stream().map(value -> value + "%").collect(Collectors.toList());
        return new String[][]{nameList.toArray(new String[nameList.size()]), valueList.toArray(new
                String[valueList.size()])};
    }
	
	private Map<String,List<String>> convertNamesAndValues(List<String> nameList,List<String> valueList){
    	Map<String,List<String>> dataMap = new HashMap<String,List<String>>();
    	String[] returnNameArr = new String[nameList.size()];
    	String[] returnValueArr = new String[valueList.size()];
    	for(int i=0;i<nameList.size();i++){
    		if(nameList.get(i).contains("二线城市")){
    			returnNameArr[0] = nameList.get(i);
    			returnValueArr[0] = valueList.get(i);
        	}
        	else if(nameList.get(i).contains("四线城市")){
        		returnNameArr[1] = nameList.get(i);
    			returnValueArr[1] = valueList.get(i);
        	}
        	else if(nameList.get(i).contains("三线城市")){
        		returnNameArr[2] = nameList.get(i);
    			returnValueArr[2] = valueList.get(i);
        	}
        	else if(nameList.get(i).contains("一线城市")){
        		returnNameArr[3] = nameList.get(i);
    			returnValueArr[3] = valueList.get(i);
        	}
        	else if(nameList.get(i).contains("白领")){
        		returnNameArr[0] = nameList.get(i);
    			returnValueArr[0] = valueList.get(i);
        	}
        	else if(nameList.get(i).contains("其他")){
        		returnNameArr[1] = nameList.get(i);
    			returnValueArr[1] = valueList.get(i);
        	}
        	else if(nameList.get(i).contains("学生")){
        		returnNameArr[2] = nameList.get(i);
    			returnValueArr[2] = valueList.get(i);
        	}
        	else if(nameList.get(i).contains("20岁以下")){
        		returnNameArr[0] = nameList.get(i);
    			returnValueArr[0] = valueList.get(i);
        	}else if(nameList.get(i).contains("20~24")){
        		returnNameArr[1] = nameList.get(i);
    			returnValueArr[1] = valueList.get(i);
        	}else if(nameList.get(i).contains("25~29")){
        		returnNameArr[2] = nameList.get(i);
    			returnValueArr[2] = valueList.get(i);
        	}else if(nameList.get(i).contains("30~34")){
        		returnNameArr[3] = nameList.get(i);
    			returnValueArr[3] = valueList.get(i);
        	}else if(nameList.get(i).contains("35~39")){
        		returnNameArr[4] = nameList.get(i);
    			returnValueArr[4] = valueList.get(i);
        	}else if(nameList.get(i).contains("40岁以上")){
        		returnNameArr[5] = nameList.get(i);
    			returnValueArr[5] = valueList.get(i);
        	}
    	}
    	
    	dataMap.put("nameList", Arrays.asList(returnNameArr));
    	dataMap.put("valueList", Arrays.asList(returnValueArr));
    	return dataMap;
    	
    }	
		
	private List<String> clearSpaces(List<String> paramlist){
    	List<String> newList = new ArrayList<String>(paramlist.size());
    	for(String str : paramlist){
    		newList.add(str.trim());
    	}
    	return newList;
    }	
		
	private String getFormattedData(String data){
        return RegexUtils.replaceStr(HtmlUtil.delHTMLTag(data), SepratorUtil.SEP_SPACE_EN,
                StringUtils.EMPTY);
    }
	
	@SuppressWarnings({ "unused"})
	private String getStarLevel(List<String> list){
		Double starLevel = 0.0;
		if(list == null || list.size()<0)
		return null;
		for(String str: list){
			if(str.contains("fullstar")){
				starLevel +=1; 
			}else if(str.contains("halfstar")){
				starLevel+=0.5;
			}
		}
		return starLevel+"";
	}
	
	private String[] matchShowingAreaAndShowingDate(String str){
			
			String[] data = new String[2];
			if(StringUtils.isNotBlank(str)){
				if(regexStr("[\u4e00-\u9fa5-:]",str).length()>=8){
					data[0] = regexStr("[\u4e00-\u9fa5]",str);
					data[1] = regexStr("[0-9:-]",str);
				}else if (StringUtils.isEmpty(regexStr("[\u4e00-\u9fa5]",str))){
					data[1] = str.trim();
					data[0] = null;
				}else if (StringUtils.isEmpty(regexStr("[0-9:-]",str))){
					data[0] = str.trim();
					data[1] = null;
				}
			}
			
			return data;
	}
	
	private String regexStr(String regex,String str){
		
		String reg = regex;

		Pattern pat = Pattern.compile(reg);  

		Matcher mat=pat.matcher(str); 

		String returnStr = mat.replaceAll("");
		
		return returnStr;
	}
	
	private String convertDateStr(String str){
    	String first = str.substring(0,4);
    	String second = str.substring(4, 6);
    	String three = str.substring(6);
    	return first+"-"+second+"-"+three;
    }
	
}
